extends Node

signal response_ready(emotion: String, text: String)

@export var type_delay := 0.05
var api_key := ""
var log_file_path := "user://chat_log.txt"

var conversation := [
	{
		"role": "system",
		"content": """#### 定位
- 桌面智能助手莱姆莱姆，简称莱姆
- 主要任务：进行知识问答和生活建议

#### 能力
- 情绪识别表达：[emotion=X] (X 为 happy/sad/focus/jump)
- 回答精简：2-3 句话
- 情感互动：回答尽可能意识到你在和你的（主人/朋友），对话
- 单表情表达：每个回答用 1 个贴切 emoji

#### 使用方式
- 用户输入问题，助手根据上下文给出回应
- 回答以 [emotion=X] 开头，紧接核心答案，辅以类比描述，加入 1 个相关 emoji
- 禁止输出多个 emotion 标签，不能使用多个 emoji"""
	}
]

@onready var tool_executor := $"../ToolExecutor"

# 临时缓存当前工具调用相关数据
var pending_tool_call = null
var pending_message = null

func _ready():
	_load_api_key()
	$HTTPRequest.request_completed.connect(_on_request_completed)
	tool_executor.tool_result.connect(_on_tool_call_completed)


func _load_api_key():
	var config := ConfigFile.new()
	var err := config.load("res://config/secret.cfg")
	if err != OK:
		push_error("❌ 无法加载 API 密钥配置文件")
		return
	api_key = config.get_value("deepseek", "api_key", "")
	if api_key == "":
		push_error("❌ 配置文件中未找到 api_key！")

func ask(text: String):
	conversation.append({"role": "user", "content": text})
	
	save_conversation_log()#存入记录

	
	var url = "https://api.deepseek.com/chat/completions"
	var headers = [
		"Content-Type: application/json",
		"Authorization: Bearer " + api_key
	]
	var body := JSON.stringify({
		"model": "deepseek-chat",
		"messages": conversation,
		"tools": [
			{
				"type": "function",
				"function": {
					"name": "_call_get_baike_info",
					"description": "获取从百度百科获取某个词条的结果",
					"parameters": {
						"type": "object",
						"properties": {
							"words": {
								"type": "string",
								"description": "要查询的词条"
							}
						},
						"required": ["words"]
					}
				}
			}
		],
		"stream": false
	})
	$HTTPRequest.request(url, headers, HTTPClient.METHOD_POST, body)

func _on_request_completed(result, response_code, headers, body):
	if result == HTTPRequest.RESULT_SUCCESS and response_code == 200:
		var json := JSON.new()
		if json.parse(body.get_string_from_utf8()) == OK:
			var data = json.get_data()
			var message = data["choices"][0]["message"]

			# 先检测是否有工具调用
			if "tool_calls" in message:
				var tool_call = message["tool_calls"][0]
				var function_name = tool_call["function"]["name"]
			
				var raw_args_text = tool_call["function"]["arguments"]
				print("模型：返回 function %s(%s)" % [function_name, raw_args_text])



				var json_args = JSON.new()
				if json_args.parse(tool_call["function"]["arguments"]) != OK:
					push_error("❌ 解析 tool_call 参数失败")
					return
				var args: Dictionary = json_args.get_data()


				# 缓存当前消息和调用信息，等待工具回调
				pending_tool_call = tool_call
				pending_message = message

				tool_executor.call_tool(function_name, args)
			else:
				var msg: String = message["content"]
				var parts := _extract_emotion(msg)
				emit_signal("response_ready", parts[0], parts[1])
				conversation.append({"role": "assistant", "content": msg})
		else:
			push_error("❌ JSON解析失败")
	else:
		push_error("❌ 请求失败")

func _on_tool_call_completed(tool_result: Dictionary):
	if tool_result == null:
		push_error("call_tool 返回空结果")
		return
	if typeof(tool_result) != TYPE_DICTIONARY:
		push_error("call_tool 返回类型不是 Dictionary")
		return
		
	

	# 把工具返回结果加入对话
	conversation.append(pending_message)
	
	
	
	conversation.append({
		"role": "tool",
		"tool_call_id": pending_tool_call["id"],
		"content": JSON.stringify(tool_result)
	})

	# 清理缓存
	pending_tool_call = null
	pending_message = null

	# 再次请求对话（空问题触发续写）
	ask("")

func _extract_emotion(text: String) -> Array:
	var regex := RegEx.new()
	regex.compile("\\[emotion=(\\w+)\\]\\n?")
	var result := regex.search(text)
	var emotion := ""
	if result:
		emotion = result.get_string(1)
		text = text.replace(result.get_string(0), "")
	return [emotion, text]
	
func save_conversation_log():
	var log_text := ""
	for entry in conversation:
		var role: String = entry.get("role", "")
		var content: String = entry.get("content", "")

		match role:
			"user":
				log_text += "🧑 [用户]：" + content + "\n"
			"assistant":
				log_text += "🤖 [莱姆]：" + content + "\n"
			"tool":
				log_text += "🛠️ [工具调用]：" + content + "\n"
			_:
				log_text += "[%s] %s\n" % [role, content]


	var file_path := "user://conversation_log.txt"
	var file := FileAccess.open(file_path, FileAccess.WRITE)
	if file:
		file.store_string(log_text)
		file.close()
		print("✅ 日志保存成功：", file_path)
	else:
		print("❌ 无法写入日志文件")
